﻿using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using WeiBeeCommon.Core;
using System.ComponentModel;
using System.Threading;
using System.IO;
using System.Xml.Serialization;
using WeiBeeCommon.DataTypes;
using OnlineLicenseConsumer;
using WeiBeeCommon.Helpers;
using System.Diagnostics;
using System.Collections.Generic;
using System.Windows.Forms;

namespace SofaExpert
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        WeiBeeSina _sina = new WeiBeeSina();
        private System.Windows.Forms.NotifyIcon notifyIcon1;
        private System.Windows.Forms.ContextMenu contextMenu1;
        public MainWindow()
        {
            InitializeComponent();            
            this.ShowInTaskbar = false;
            this.notifyIcon1 = new System.Windows.Forms.NotifyIcon();
            notifyIcon1.Text = @"新浪微博V5沙发";
            notifyIcon1.Icon = SofaExpert.Properties.Resources.Systray;
            //MenuItem menuItemComments = new MenuItem(@"设置沙发句");
            MenuItem menuItemChangeAccount = new MenuItem(@"换个账号");
            MenuItem menuItemSearchKeywords = new MenuItem(@"设置关键词");
            MenuItem menuItemExit = new MenuItem(@"退出");
            MenuItem menuItemOpenfolder = new MenuItem(@"打开程序文件夹");
            //menuItemComments.Click += new EventHandler(menuItemComments_Click);
            menuItemChangeAccount.Click += new EventHandler(menuItemChangeAccount_Click);
            menuItemSearchKeywords.Click += new EventHandler(menuItemSearchKeywords_Click);
            menuItemExit.Click += new EventHandler(menuItemExit_Click);
            menuItemOpenfolder.Click += new EventHandler(menuItemOpenfolder_Click);
            this.contextMenu1 = new System.Windows.Forms.ContextMenu();
            this.contextMenu1.MenuItems.Add(menuItemChangeAccount);
            //this.contextMenu1.MenuItems.Add(menuItemComments);
            this.contextMenu1.MenuItems.Add(menuItemSearchKeywords);
            this.contextMenu1.MenuItems.Add(menuItemOpenfolder);
            this.contextMenu1.MenuItems.Add(menuItemExit);
            notifyIcon1.ContextMenu = this.contextMenu1;
            notifyIcon1.MouseClick += new System.Windows.Forms.MouseEventHandler(notifyIcon1_MouseClick);
            notifyIcon1.Visible = true;
        }

        void menuItemOpenfolder_Click(object sender, EventArgs e)
        {
            var proc = new Process();
            proc.StartInfo.FileName = "explorer.exe";
            proc.StartInfo.Arguments = AppDomain.CurrentDomain.BaseDirectory;
            proc.Start();
        }

        void menuItemSearchKeywords_Click(object sender, EventArgs e)
        {
            var searchForm = new SetKeyword();
            if (searchForm.ShowDialog() == true)
            {
                System.Windows.MessageBox.Show("换关键词后请手动重启，更新，主程序关闭");
                this.Close();
            }
        }

        void menuItemChangeAccount_Click(object sender, EventArgs e)
        {
            SinaAccountSetup();
            System.Windows.MessageBox.Show("换账号后请手动重启，更新，主程序关闭");
            this.Close();
        }

        void menuItemExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        void menuItemComments_Click(object sender, EventArgs e)
        {
            System.Windows.MessageBox.Show("menuItemComments_Click");
        }

        void notifyIcon1_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (this.WindowState == WindowState.Minimized)
                this.WindowState = WindowState.Normal;
            this.Activate();
        }

        List<AuthEntity> weibeeList = new List<AuthEntity>();
        EntityHelper entityHelper = new EntityHelper();
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            weibeeList = entityHelper.LoadEntities();
            if (weibeeList.Count == 0 || string.IsNullOrEmpty(weibeeList[0].Token))
            {
                SinaAccountSetup();
            }
            if (string.IsNullOrEmpty(weibeeList[0].Token))
            {
                System.Windows.MessageBox.Show("用户名密码错误?退出程序.");
                this.Close();
            }
            _sina.OAuth.ConsumerKey = weibeeList[0].ConsumerKey;
            _sina.OAuth.ConsumerSecret = weibeeList[0].ConsumerSecret;
            _sina.OAuth.Token = weibeeList[0].Token;
            _sina.OAuth.TokenSecret = weibeeList[0].TokenSecret;
            _bgwWeiBeeUser.DoWork += new DoWorkEventHandler(_bgwWeiBeeUser_DoWork);
            _bgwWeiBeeUser.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bgwWeiBeeUser_RunWorkerCompleted);
            _bgwWeiBeeUser.RunWorkerAsync();

            InitSinaVisit();

            BeginGetLeftTimes();
        }

        private void SinaAccountSetup()
        {
            var form = new Pages.SinaUser();
            form.ShowDialog();
            weibeeList = entityHelper.LoadEntities();
        }

        #region WeiBeeUserUpdate
        readonly BackgroundWorker _bgwWeiBeeUser = new BackgroundWorker();
        string weibeeUserid;
        SinaUser _me;
        SinaUser Me
        {
            get
            {
                if (_me == null)
                {
                    _me = _sina.GetWeiBeeUser() as SinaUser;
                }
                return _me;
            }
        }
        void _bgwWeiBeeUser_DoWork(object sender, DoWorkEventArgs e)
        {
            weibeeUserid = Me.id;
        }
        void _bgwWeiBeeUser_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (_me == null)
            {
                System.Windows.MessageBox.Show("Not get user info");
                SinaAccountSetup();
                return;
            }
            this.lbUserInfo.Content = GetAboutMe();
        }

        private string GetAboutMe()
        {
            return string.Format("@{0},关注数{1},粉丝数{2},围脖数{3}", Me.name, Me.friends_count, Me.followers_count, Me.statuses_count);
        }
        #endregion WeiBeeUserUpdate

        #region VisitSinaByCommentPublictimeline
        readonly BackgroundWorker _bgwSinaVisit = new BackgroundWorker();
        System.Windows.Forms.Timer _sinaVisitByComment;
        void _sinaVisitByComment_Tick(object sender, EventArgs e)
        {
            if (!_bgwSinaVisit.IsBusy)
            {
                _bgwSinaVisit.RunWorkerAsync();
            }
        }
        BatchComment batchComment;
        void BgwSinaVisit_DoWork(object sender, DoWorkEventArgs e)
        {
            if (_sina.IsEnabled && LeftTimes > 0)
            {
                if (batchComment == null)
                {
                    batchComment = new BatchComment(_sina);
                    for (int i = 1; i < weibeeList.Count; i++)
                    {
                        var weibee = new WeiBeeSina();
                        weibee.OAuth = new OAuthSina();
                        weibee.OAuth.ConsumerKey = weibeeList[i].ConsumerKey;
                        weibee.OAuth.ConsumerSecret = weibeeList[i].ConsumerSecret;
                        weibee.OAuth.Token = weibeeList[i].Token;
                        weibee.OAuth.TokenSecret = weibeeList[i].TokenSecret;
                        batchComment.AddOneWeiBee(weibee);
                    }
                }
                Debug.Assert(batchComment!=null);
                _resultstring = batchComment.Comment();
            }
        }
        string _resultstring;
        void _bgwSinaVisit_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (string.IsNullOrEmpty(_resultstring) || _resultstring.StartsWith("Error",true,System.Globalization.CultureInfo.CurrentCulture)) return;
            this.tbResult.Text += GetCommentProfile(_resultstring) + Environment.NewLine;
        }
        private string GetCommentProfile(string resultstring)
        {
            try
            {
                const string blank = @"<?xml version=""1.0"" encoding=""UTF-8""?>";
                if (resultstring.Length <= blank.Length) return "commented"; // To fix bug //bug if resultstring like "<?xml version="1.0" encoding="UTF-8"?>" the following line will throw exception

                Comment result = null;
                using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(resultstring)))
                {
                    var ser = new XmlSerializer(typeof(Comment));
                    result = ser.Deserialize(ms) as Comment;
                }
                if (result != null)
                {
                    return string.Format("{0},@{1},时间:{2},内容:{3},评论:{4}",
                                         GetShortTimeString(result.created_at),
                                         result.status.user.name,
                                         GetShortTimeString(result.status.created_at),
                                         GenerateSubstring(result),
                                         result.text.Substring(0, GetLengthNoGreaterThenTen(result.text)));
                }
            }
            catch(Exception ex)
            {
                SaveLog(string.Format("callstack={0},resultstring={1},exinformation={2}",
                    ex.StackTrace, resultstring, ex.Message));
            }
           return "commented";
        }

        private string GetShortTimeString(string longtime)
        {
            Regex re = new Regex("\\d\\d:\\d\\d:\\d\\d", RegexOptions.None);
            MatchCollection mc = re.Matches(longtime);
            return mc[0].Value;
        }

        private int GetLengthNoGreaterThenTen(string p)
        {
            return (p.Length > 10)?10:p.Length;
        }

        private string GenerateSubstring(Comment result)
        {
            return result.status.text.Substring(0, GetLengthNoGreaterThenTen(result.status.text));
        }

        private void InitSinaVisit()
        {
            _bgwSinaVisit.DoWork += new DoWorkEventHandler(BgwSinaVisit_DoWork);
            _bgwSinaVisit.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bgwSinaVisit_RunWorkerCompleted);
            _sinaVisitByComment = new System.Windows.Forms.Timer();
            _sinaVisitByComment.Tick += new EventHandler(_sinaVisitByComment_Tick);
            _sinaVisitByComment.Interval = 60013;// / this.weibeeList.Count;
            _sinaVisitByComment.Start();
        }
        #endregion 

        #region OnlineCheck
        readonly BackgroundWorker _bgwOnlineCheck = new BackgroundWorker();

        string WeiBeeUserId
        {
            get
            {
                if (string.IsNullOrEmpty(this.weibeeUserid))
                {
                    this.weibeeUserid = _sina.GetUserId();
                }
                return this.weibeeUserid;
            }
        }
        int? _leftTimes;
        int LeftTimes
        {
            get
            {
                if (!_leftTimes.HasValue && !_bgwOnlineCheck.IsBusy)
                {
                    BeginGetLeftTimes();
                }
                return _leftTimes.GetValueOrDefault();
            }
        }
        void BeginGetLeftTimes()
        {
            _bgwOnlineCheck.DoWork += new DoWorkEventHandler(_bgwOnlineCheck_DoWork);
            _bgwOnlineCheck.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bgwOnlineCheck_RunWorkerCompleted);
            _bgwOnlineCheck.RunWorkerAsync();
            _onlineCheckTimer = new System.Windows.Forms.Timer();
            _onlineCheckTimer.Tick += new EventHandler(UpdateLeftTimes);
            _onlineCheckTimer.Interval = 60*60*1000; // 1 hour, and will be 24 hours
            _onlineCheckTimer.Start();
        }

        void UpdateLeftTimes(object sender, EventArgs e)
        {
            if (!_bgwOnlineCheck.IsBusy)
            {
                _bgwOnlineCheck.RunWorkerAsync();
            }
        }
        System.Windows.Forms.Timer _onlineCheckTimer;
        void _bgwOnlineCheck_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.lbAd.Content = string.Format("剩余使用天数:{0},购买使用天数请联系QQ1800@GMAIL.COM,QQ:6763745", LeftTimes);
        }

        void _bgwOnlineCheck_DoWork(object sender, DoWorkEventArgs e)
        {
            Consumer target = new Consumer();
            string id = WeiBeeUserId;
            _leftTimes = target.GetLeftTimes(id);
        }
        #endregion OnlineCheck

        private static AsyncCallback SyncContextCallback(AsyncCallback callback)
        {
            SynchronizationContext sc = SynchronizationContext.Current;
            if (sc == null) return callback;
            return asyncResult => sc.Post(result => callback((IAsyncResult)result), asyncResult);
        }

        private void btClear_Click(object sender, RoutedEventArgs e)
        {
            tbResult.Text = string.Empty;
        }

        private static void SaveLog(string errorinformation)
        {
            const string logfile = "log.txt";
            using (FileStream fs = new FileStream(logfile, FileMode.OpenOrCreate, FileAccess.Write))
            {
                try
                {
                    string outstring = string.Format("{0} - {1}",DateTime.Now.ToString(),errorinformation);
                    byte[] data = new UTF8Encoding().GetBytes(outstring);
                    fs.Write(data,0,data.Length);                   
                }
                catch
                {
                }
            }
        }

        private void btOpenFolder_Click(object sender, RoutedEventArgs e)
        {
            var proc = new Process();
            proc.StartInfo.FileName = "explorer.exe";
            proc.StartInfo.Arguments = AppDomain.CurrentDomain.BaseDirectory;
            proc.Start();
        }

        private void buttonFollow_Click(object sender, RoutedEventArgs e)
        {
            Action action = new Action(() =>
            {
                _sina.CreateFollow("1118932467");
            });
            action.BeginInvoke(null, null);
        }
    }
}
